﻿using System.Timers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.AspNet.SignalR.Client;
using System.Net;
using System.Threading.Tasks;
using Api.Common;

namespace PushTask
{
    public class SendSignalrMessage
    {
        string apiurl = ConfigHelper.GetConfigString("signalrServer");

        static HubConnection conn = null;
        static IHubProxy msgProxy = null;
        public void Send(string message, string[] deviceStrs)
        {
            LogHelper.WriteCreateNewLog(LogType.signalrInfo, "调用Signalr后台服务");
            Timer timer = new Timer(2000);
            timer.Enabled = true;
            timer.AutoReset = true;

            if (conn == null)
            {
                Init().ContinueWith((t) => DoThings(message, deviceStrs));
            }
            else
            {
                DoThings(message, deviceStrs);
            }
        }

        private void DoThings(string message, string[] deviceStrs)
        {
            msgProxy.Invoke("send", message, deviceStrs);
        }
        private System.Threading.Tasks.Task Link()
        {
            return conn.Start().ContinueWith((t) =>
            {
                if (t.IsCompleted)
                {
                    if (t.Status == TaskStatus.Faulted)
                    {
                        conn = null;
                        string str = string.Empty;
                        if (t.Exception?.InnerException != null)
                        {
                            str = t.Exception.InnerException.Message;
                        }
                        else
                        {
                            str = t.Exception.Message;
                        }
                        Console.WriteLine(str);
                        LogHelper.WriteLongLog(LogType.signalrError, "建立连接失败");
                    }
                }
            });
        }
        private Task Init()
        {
            if (conn == null)
            {
                conn = new HubConnection(apiurl, false);
                ServicePointManager.DefaultConnectionLimit = 1;//限制并发数量
                conn.TraceLevel = TraceLevels.All;
                conn.Error += Conn_Error;
                msgProxy = conn.CreateHubProxy("MsgHub");
                conn.Headers.Add("siteId", "0");
                conn.Headers.Add("machineKey", "console");
                conn.Headers.Add("isadmin", "true");

                conn.Headers.Add("name", "zr");
                conn.Headers.Add("pwd", "0d9ccc4ba0");

                conn.StateChanged += Conn_StateChanged;
                conn.TransportConnectTimeout = new TimeSpan(0, 0, 3);

                try
                {
                    msgProxy.On<string>("Receive", (message) => AddReceiveMsg(message));

                    msgProxy.On<string>("MsgReceive", (message) => AddReceiveMsg(message));

                    msgProxy.On<string>("OrderReceive", message => AddReceiveMsg(message));

                    msgProxy.On("Error", exception => AddReceiveMsg(exception));

                    //該admin客戶端停止連接
                    msgProxy.On("Stop", () =>
                    {
                        conn.Stop();
                    });
                }
                catch (HubException ex)
                {
                    LogHelper.WriteLongLog(LogType.signalrError, ex?.Message);
                }
            }

            if (conn != null && conn.State == ConnectionState.Disconnected)
            {
                return Link();
            }
            return Task.FromResult<int>(1);
        }
        private void Conn_StateChanged(StateChange obj)
        {
            switch (obj.NewState)
            {
                case ConnectionState.Connected:
                    Console.WriteLine("已连接");
                    break;
                case ConnectionState.Connecting:
                    Console.WriteLine("连接中...");
                    break;
                case ConnectionState.Disconnected:
                    Console.WriteLine("断线...");
                    Init();
                    break;
                case ConnectionState.Reconnecting:
                    Console.WriteLine("断线连接中...");
                    break;
            }
        }
        private void AddReceiveMsg(string message)
        {
            Console.WriteLine(message);
            LogHelper.WriteLongLog(LogType.signalrInfo, message);
        }
        private void Conn_Error(Exception obj)
        {
            AddReceiveMsg(obj?.Message);
        }
    }
}
